import re
import requests
import json
from django.db import transaction
from django.core import signing
from rest_framework.decorators import api_view
from questionnaire.models import Questionnaire, Question, Options, GradeQuestionAttribute, Submit, Answer
from rest_framework.response import Response
from rest_framework import status
import datetime
import pytz
from questionnaire.views_statistics import totalQuestionnaire
import geoip2.database


# 计算每个选项的选择人数
def optionCount(option_id, ls_submitted):
    answer_count = Answer.objects.filter(answer=option_id).filter(submitId__in=ls_submitted).count()
    return answer_count


# 更新每个选项的remain值
def updateRemain(questionnaire_id):
    ls_submitted = list(
        Submit.objects.filter(wjId=questionnaire_id).filter(is_submitted=True).values_list('id', flat=True))
    questions = Question.objects.filter(wjId=questionnaire_id)
    for question in questions:
        if question.type in ['single', 'multi']:
            options = Options.objects.filter(questionId=question.id)
            for option in options:
                if option.remain is not None:
                    option.remain = option.limit - optionCount(option.id, ls_submitted)
                    option.save()


# 判断问卷的所有所选项限额都为 0
def allEmpty(questionnaire_id):
    questions = Question.objects.filter(wjId=questionnaire_id)
    question_zero = 0
    for question in questions:
        if question.type in ['single', 'multi']:
            options = Options.objects.filter(questionId=question.id)
            option_zero = 0
            for option in options:
                if option.remain == 0:
                    option_zero += 1
            if option_zero == Options.objects.filter(questionId=question.id).count():
                question_zero += 1
    if question_zero == Question.objects.filter(wjId=questionnaire_id, type='single').count() + Question.objects.filter(
            wjId=questionnaire_id, type='multi').count():
        return True
    return False


# 判断当前的remain是否等于0
def checkRemain(questionnaire_id, submit_id):
    questions = Question.objects.filter(wjId=questionnaire_id)
    for question in questions:
        if question.type in ['single', 'multi']:
            options = Options.objects.filter(questionId=question.id)
            for option in options:
                # 如果某个选项是0但是页面上没及时更新，显示不为0 用户选了该选项
                answer_count = Answer.objects.filter(questionId=question.id, submitId=submit_id,
                                                     answer=option.id).count()
                if option.remain == 0 and answer_count != 0:
                    return False
    return True


@api_view(['POST', ])
def checkQuestionnaire(request):
    questionnaire_id = request.data.get('questionnaire_id')
    if Questionnaire.objects.filter(id=questionnaire_id).count() == 0:
        return Response({'code': -1, 'msg': '问卷不存在'}, status=status.HTTP_200_OK)
    questionnaire = Questionnaire.objects.get(id=questionnaire_id)
    if questionnaire.is_deleted:
        return Response({'code': -2, 'msg': '问卷已被发布者删除'}, status=status.HTTP_200_OK)
    if questionnaire.status == 0:
        return Response({'code': -3, 'msg': '问卷未发布'}, status=status.HTTP_200_OK)
    if questionnaire.is_set_date:
        if questionnaire.start_time is not None:
            now = datetime.datetime.now().replace(tzinfo=pytz.timezone('UTC'))
            if questionnaire.start_time > now:
                return Response({'code': -4, 'msg': '未到开始时间'}, status.HTTP_200_OK)
        if questionnaire.end_time is not None:
            now = datetime.datetime.now().replace(tzinfo=pytz.timezone('UTC'))
            if questionnaire.end_time < now:
                return Response({'code': -5, 'msg': '已过截至时间'}, status.HTTP_200_OK)
    #     此处还有一个关于二次填写的拦截：禁止二次填写 允许修改可修改的问卷
    ip = request.data.get('ip')
    if ip is None:
        return Response({'code': -6, 'msg': '参数错误:缺少ip'}, status.HTTP_200_OK)  # 正常情况下 不会出现这种错误
    if Submit.objects.filter(wjId=questionnaire_id, submitIp=ip).count() != 0:  # 如果填写过问卷
        if Submit.objects.get(wjId=questionnaire_id, submitIp=ip).is_submitted:  # 如果提交了
            if questionnaire.is_allowed_to_change:
                return Response({'code': -8, 'msg': '再次填写'}, status=status.HTTP_200_OK)
            else:
                return Response({'code': -7, 'msg': '您已提交问卷'}, status=status.HTTP_200_OK)
        else:
            return Response({'code': -8, 'msg': '再次填写'}, status=status.HTTP_200_OK)
    if questionnaire.type == " apply" and (
            questionnaire.limit == totalQuestionnaire(questionnaire_id) or allEmpty(questionnaire_id)):
        return Response({'code': -9, 'msg': '达到最大填写人数'}, status=status.HTTP_200_OK)
    else:
        return Response({'code': 0, 'msg': '允许填写'}, status=status.HTTP_200_OK)


@api_view(['POST', ])
def fillInPositioning(request):


    ip = request.data.get('ip')
    if ip is None:
        return Response({'msg': 'ip is null', 'code': -1}, status=status.HTTP_400_BAD_REQUEST)
    r = requests.get('https://api.ip138.com/ip/?ip=%s&datatype=jsonp&token=9e74490f88b67e309ceaf86ee7731637' % ip)
    data = json.loads(r.text).get('data')
    answer = data[0] + ' ' + data[1] + ' ' + data[2]
    return Response({'msg': '获取地址成功', 'answer': answer, 'code': 0}, status=status.HTTP_200_OK)


# 其中有计时或者必答等问题，由前端进行判断，这里不会给出报错。
@api_view(['POST', ])
@transaction.atomic
def answerQuestionnaire(request):
    questionnaire_id = request.data.get('id')
    questions = request.data.get('questions')
    if questionnaire_id is None or questions is None:
        return Response({'code': -1, 'msg': '参数错误:缺少id或questions'}, status.HTTP_400_BAD_REQUEST)
    ip = request.data.get('ip')
    if ip is None:
        return Response({'code': -1, 'msg': '参数错误:缺少ip'}, status.HTTP_400_BAD_REQUEST)
    # s1 = transaction.savepoint()  # 设置事务保存点 回滚使用
    if Submit.objects.filter(wjId=questionnaire_id, submitIp=ip).count() != 0:  # 如果提交过问卷 则提交设置为上一次的提交
        submit = Submit.objects.get(wjId=questionnaire_id, submitIp=ip)
    else:
        submit = Submit.objects.create(wjId=questionnaire_id, submitIp=ip)  # 如果没提交过问卷 则新建一个提交
    Answer.objects.filter(submitId=submit.id, wjId=questionnaire_id).delete()
    for question in questions:
        question_id = question.get('id')
        type = question.get('type')
        if type is None or question_id is None:  # 如果参数出现错误 就删除提交
            submit.delete()
            return Response({'code': -1, 'msg': '参数错误:缺少type或question_id'}, status.HTTP_400_BAD_REQUEST)
        if Question.objects.filter(id=question_id).count() == 0:
            return Response({'code': -1, 'msg': '参数错误:question不存在'}, status.HTTP_400_BAD_REQUEST)
        question_object = Question.objects.get(id=question_id)
        if question_object.wjId != questionnaire_id:
            return Response({'code': -1, 'msg': '参数错误:question不属于questionnaire'}, status.HTTP_400_BAD_REQUEST)
        if question.get('type') != type:
            return Response({'code': -1, 'msg': '参数错误:type不是question的type, question的type是' + question.type},
                            status.HTTP_400_BAD_REQUEST)
        Answer.objects.filter(questionId=question_id, submitId=submit.id, wjId=questionnaire_id).delete()
        if type == 'multi' or type == 'single':
            Answer.objects.filter(questionId=question_id, submitId=submit.id, wjId=questionnaire_id).delete()
            options = question.get('options')
            if options is None:
                return Response({'code': -1, 'msg': '参数错误:缺少options'}, status.HTTP_400_BAD_REQUEST)
            for option in options:
                option_id = option.get('option_id')
                if option_id is None:
                    submit.delete()
                    return Response({'code': -1, 'msg': '参数错误:缺少option_id'}, status.HTTP_400_BAD_REQUEST)
                if Options.objects.filter(id=option_id).count() == 0:
                    submit.delete()
                    return Response({'code': -1, 'msg': '参数错误:option不存在'}, status.HTTP_400_BAD_REQUEST)
                option_object = Options.objects.get(id=option_id)
                if option_object.questionId != question_id:
                    submit.delete()
                    return Response({'code': -1, 'msg': '参数错误:option不属于该问题'}, status.HTTP_400_BAD_REQUEST)
                Answer.objects.create(questionId=question_id, submitId=submit.id, wjId=questionnaire_id, type=type,
                                      answer=option_id)
        elif type == 'fill':
            text = question.get('text')
            if text is None:
                submit.delete()
                return Response({'code': -1, 'msg': '参数错误:缺少text'}, status.HTTP_400_BAD_REQUEST)
            Answer.objects.create(questionId=question_id, submitId=submit.id, wjId=questionnaire_id, type=type,
                                  answerText=text)
        elif type == 'grade':
            grade = question.get('answer')
            if grade is None:
                submit.delete()
                return Response({'code': -1, 'msg': '参数错误:缺少answer'}, status.HTTP_400_BAD_REQUEST)
            Answer.objects.create(questionId=question_id, submitId=submit.id, wjId=questionnaire_id, type=type,
                                  answer=grade)
        else:
            submit.delete()
            return Response({'code': -1, 'msg': '参数错误:错误的type'}, status.HTTP_400_BAD_REQUEST)
    return Response({'code': 0, 'msg': '创建成功', 'id': submit.id}, status.HTTP_200_OK)


@api_view(['POST', ])
@transaction.atomic
def submitQuestionnaire(request):
    submit_id = request.data.get('id')
    if submit_id is None:
        return Response({'code': -1, 'msg': '参数错误:缺少id'}, status.HTTP_400_BAD_REQUEST)
    use_time = request.data.get('use_time')
    if use_time is None:
        return Response({'code': -1, 'msg': '参数错误:缺少use_time'}, status.HTTP_400_BAD_REQUEST)
    if Submit.objects.filter(id=submit_id).count() == 0:
        return Response({'code': -1, 'msg': '参数错误:不存在的commit_id'}, status.HTTP_400_BAD_REQUEST)
    username = request.data.get('username')
    submit = Submit.objects.get(id=submit_id)
    questionnaire_id = submit.wjId
    questionnaire = Questionnaire.objects.get(id=questionnaire_id)
    if totalQuestionnaire(questionnaire_id) == questionnaire.limit:
        return Response({'code': -2, 'msg': '达到最大提交人数'}, status.HTTP_200_OK)
    if questionnaire.type == "apply":
        updateRemain(questionnaire_id)
        if not checkRemain(questionnaire_id, submit_id):
            return Response({'code': -3, 'msg': '请勿选择选项限额为 0的选项'}, status.HTTP_200_OK)
        if allEmpty(questionnaire_id):
            return Response({'code': -2, 'msg': '达到最大提交人数'}, status.HTTP_200_OK)
    now = datetime.datetime.now().replace(tzinfo=pytz.timezone('UTC'))
    # tz = pytz.timezone('Asia/Shanghai')
    # now = datetime.datetime.now(tz)
    submit.submitTime = now
    submit.is_submitted = True
    submit.useTime = use_time
    submit.username = username
    submit.save()
    updateRemain(questionnaire_id)
    return Response({'code': 0, 'msg': '提交成功'}, status.HTTP_200_OK)


@api_view(['POST', ])
def getAnswers(request):
    ip = request.data.get('ip')
    if ip is None:
        return Response({'code': -1, 'msg': '参数错误:缺少ip'}, status.HTTP_200_OK)
    questionnaire_id = request.data.get('questionnaire_id')
    if questionnaire_id is None:
        return Response({'code': -1, 'msg': '缺少questionnaire_id'}, status.HTTP_200_OK)
    if Questionnaire.objects.filter(id=questionnaire_id).count() == 0:
        return Response({'code': -1, 'msg': '不存在的questionnaire_id'}, status.HTTP_200_OK)
    if Submit.objects.filter(submitIp=ip, wjId=questionnaire_id).count() == 0:
        return Response({'code': -1, 'msg': '没提交过'}, status.HTTP_200_OK)
    submit = Submit.objects.get(submitIp=ip, wjId=questionnaire_id)
    response = {'id': questionnaire_id}
    questions = []
    tag = set()
    answers = Answer.objects.filter(submitId=submit.id, wjId=questionnaire_id)
    for answer in answers:
        if answer.type == 'multi' or answer.type == 'single':
            if answer.questionId in tag:
                for item in questions:
                    if item['id'] == answer.questionId:
                        question = item
                        question['options'].append({'option_id': answer.answer})
                        break
            else:
                tag.add(answer.questionId)
                question = {'id': answer.questionId, 'type': answer.type}
                options = [{'option_id': answer.answer}, ]
                question['options'] = options
                questions.append(question)
        if answer.type == 'grade':
            question = {'id': answer.questionId, 'type': answer.type, 'answer': answer.answer}
            questions.append(question)
        if answer.type == 'fill':
            question = {'id': answer.questionId, 'type': answer.type, 'text': answer.answerText}
            questions.append(question)
    response['questions'] = questions
    return Response(response, status=status.HTTP_200_OK)
